"""
双向链表（Doubly Linked List）是一种更复杂的链表，它的每个节点都有两个链接，一个指向前一个节点，另一个指向下一个节点。这种数据结构允许我们从两个方向遍历链表，使得在查找、插入和删除操作时具有更大的灵活性。常见的双向链表操作包括添加元素（add）、删除元素（remove）、获取元素（get）、链表是否为空（is_empty）、链表的长度（size）等。

以下是使用 Python 实现的一个简单双向链表。双向链表类将包含以下操作：
添加元素(add)
删除元素(remove)
获取元素(get)
链表是否为空(is_empty)
链表的长度(size)
"""

class Node:
    def __init__(self, data=None):
        self.data = data
        self.next = None
        self.prev = None


class DoublyLinkedList:
    def __init__(self):
        self.head = None

    def is_empty(self):
        return self.head is None

    def add(self, data):
        new_node = Node(data)
        new_node.next = self.head
        if self.head:
            self.head.prev = new_node
        self.head = new_node

    def size(self):
        node = self.head
        count = 0
        while node:
            count += 1
            node = node.next
        return count

    def get(self, index):
        node = self.head
        for i in range(index):
            if not node:
                return None
            node = node.next
        return node.data if node else None

    def remove(self, data):
        node = self.head
        while node:
            if node.data == data:
                if node.prev:
                    node.prev.next = node.next
                if node.next:
                    node.next.prev = node.prev
                if node == self.head:
                    self.head = node.next
                return True
            node = node.next
        return False
    
    def print(self):
        """在 ASCII 图形表示中，双向链表可以被视为一种水平的数据结构，其中每个节点包含数据和指向下一个节点以及前一个节点的指针。例如，一个包含元素 1、2、3 的双向链表可以表示为：
        head <->3 <-> 2 <-> 1
        """
        node = self.head
        print('head<->', end='')
        while node:
            print(node.data, end='')
            node = node.next
            if not node:
                print()
                break
            print(end='<->')


if __name__ == '__main__':
    dll = DoublyLinkedList()
    print(dll.is_empty())  # True

    dll.add(1)
    dll.add(2)
    dll.add(3)
    print(dll.size())  # 3
    dll.print() # head<->3<->2<->1
    print(dll.get(1))  # 2

    dll.remove(2)
    print(dll.get(1))  # 1

    print(dll.size())  # 2
    dll.print() # head<->3<->1
